/**
 * 比较两个 location 对象是否相同
 * @param {*} a 
 * @param {*} b 
 * @returns 
 */
export function locationsAreEqual(a, b) {
    return a.pathname === b.pathname && a.search === b.search && a.hash === b.hash && a.key === b.key && valueEqual(a.state, b.state);
}

/**
 * 比较两个值是否相等
 * @param {*} a 
 * @param {*} b 
 * @returns 
 */
function valueEqual(a, b) {
    if (a === b) return true;
    if (a == null || b == null) return false;
    if (Array.isArray(a)) {
        return Array.isArray(b) && a.length === b.length && a.every(function (item, index) {
            return valueEqual(item, b[index]);
        });
    }
    var aType = typeof a === 'undefined' ? 'undefined' : typeof a;
    var bType = typeof b === 'undefined' ? 'undefined' : typeof b;
    if (aType !== bType) return false;
    if (aType === 'object') {
        var aValue = a.valueOf();
        var bValue = b.valueOf();
        if (aValue !== a || bValue !== b) return valueEqual(aValue, bValue);
        var aKeys = Object.keys(a);
        var bKeys = Object.keys(b);
        if (aKeys.length !== bKeys.length) return false;
        return aKeys.every(function (key) {
            return valueEqual(a[key], b[key]);
        });
    }
    return false;
}